# Copyright (c) Meta Platforms, Inc. and affiliates.

import re

UNICODE_TO_LATEX = {
    "α": "\\alpha",
    "β": "\\beta",
    "γ": "\\gamma",
    "δ": "\\delta",
    "ε": "\\epsilon",
    "ζ": "\\zeta",
    "η": "\\eta",
    "θ": "\\theta",
    "ι": "\\iota",
    "κ": "\\kappa",
    "λ": "\\lambda",
    "μ": "\\mu",
    "ν": "\\nu",
    "ξ": "\\xi",
    "π": "\\pi",
    "ρ": "\\rho",
    "σ": "\\sigma",
    "τ": "\\tau",
    "υ": "\\upsilon",
    "φ": "\\phi",
    "χ": "\\chi",
    "ψ": "\\psi",
    "ω": "\\omega",
    "Γ": "\\Gamma",
    "Δ": "\\Delta",
    "Θ": "\\Theta",
    "Λ": "\\Lambda",
    "Ξ": "\\Xi",
    "Π": "\\Pi",
    "Σ": "\\Sigma",
    "Υ": "\\Upsilon",
    "Φ": "\\Phi",
    "Ψ": "\\Psi",
    "Ω": "\\Omega",
    "∀": "\\forall",
    "∂": "\\partial",
    "∃": "\\exists",
    "∄": "\\nexists",
    "∅": "\\emptyset",
    "∇": "\\nabla",
    "∈": "\\in",
    "∉": "\\notin",
    "∋": "\\ni",
    "∏": "\\prod",
    "∑": "\\sum",
    "−": "-",
    "∗": "\\ast",
    "√": "\\sqrt",
    "∛": "\\sqrt[3]",
    "∝": "\\propto",
    "∞": "\\infty",
    "∠": "\\angle",
    "∧": "\\wedge",
    "∨": "\\vee",
    "∩": "\\cap",
    "∪": "\\cup",
    "∫": "\\int",
    "∬": "\\iint",
    "∭": "\\iiint",
    "∮": "\\oint",  # codespell:ignore
    "∴": "\\therefore",
    "∵": "\\because",
    "∼": "\\sim",
    "≃": "\\simeq",
    "≅": "\\cong",
    "≈": "\\approx",
    "≠": "\\neq",
    "≡": "\\equiv",
    "≤": "\\leq",
    "≥": "\\geq",
    "⊂": "\\subset",
    "⊃": "\\supset",
    "⊄": "\\nsubset",
    "⊆": "\\subseteq",
    "⊇": "\\supseteq",
    "⊕": "\\oplus",
    "⊗": "\\otimes",
    "⊥": "\\bot",
    "⋅": "\\cdot",
    "⌈": "\\lceil",
    "⌉": "\\rceil",
    "⌊": "\\lfloor",
    "⌋": "\\rfloor",
    "⟂": "\\perp",
    "±": "\\pm",
    "∓": "\\mp",
    "×": "\\times",
    "÷": "\\div",
    "↑": "\\uparrow",
    "↓": "\\downarrow",
    "↔": "\\leftrightarrow",
    "→": "\\rightarrow",
    "←": "\\leftarrow",
    "⇒": "\\Rightarrow",
    "⇐": "\\Leftarrow",
    "⇔": "\\Leftrightarrow",
    "ℵ": "\\aleph",
    "ℏ": "\\hbar",
    "ℑ": "\\Im",
    "ℓ": "\\ell",
    "ℕ": "\\mathbb{N}",
    "ℙ": "\\mathbb{P}",
    "ℚ": "\\mathbb{Q}",
    "ℝ": "\\mathbb{R}",
    "ℤ": "\\mathbb{Z}",
    "ℂ": "\\mathbb{C}",
    "∘": "\\circ",
    "∙": "\\bullet",
    "∎": "\\blacksquare",
    "∐": "\\coprod",
    "∖": "\\setminus",
    "≊": "\\approxeq",
    "≪": "\\ll",
    "≫": "\\gg",
    "⊅": "\\nsupset",
    "⊈": "\\nsubseteq",
    "⊉": "\\nsupseteq",
    "⊊": "\\subsetneq",
    "⊋": "\\supsetneq",
    "⊖": "\\ominus",
    "⊘": "\\oslash",
    "⊙": "\\odot",
    "⊚": "\\circledcirc",
    "⊛": "\\circledast",
    "⊝": "\\circleddash",
    "⊞": "\\boxplus",
    "⊟": "\\boxminus",
    "⊠": "\\boxtimes",
    "⊡": "\\boxdot",
    "⊢": "\\vdash",
    "⊣": "\\dashv",
    "⊤": "\\top",
    "⊨": "\\models",
    "⊴": "\\unlhd",
    "⊵": "\\unrhd",
    "⋀": "\\bigwedge",
    "⋁": "\\bigvee",
    "⋂": "\\bigcap",
    "⋃": "\\bigcup",
    "⋆": "\\star",
    "⋈": "\\bowtie",
    "⌶": "\\APLsquish",
    "⌷": "\\APLquad",
    "⌸": "\\APL1",
    "⌹": "\\APLlefttack",
    "⌺": "\\APLrighttack",
    "⌻": "\\APLbottomcircle",
    "⌼": "\\APLtopunderscore",
    "⌽": "\\APLcircle",
    "⌿": "\\APLslash",
    "⍀": "\\APLbackslash",
    "⍼": "\\eqdef",
    "⎰": "\\ulcorner",
    "⎱": "\\urcorner",
    "⎲": "\\llcorner",
    "⎳": "\\lrcorner",
    "⏜": "\\frown",
    "⏝": "\\smile",
    "▷": "\\triangleright",
    "◁": "\\triangleleft",
    "◊": "\\diamond",
    "○": "\\circ",
    "●": "\\bullet",
    "★": "\\bigstar",
    "♠": "\\spadesuit",
    "♡": "\\heartsuit",
    "♢": "\\diamondsuit",
    "♣": "\\clubsuit",
    "♭": "\\flat",
    "♮": "\\natural",
    "♯": "\\sharp",
    "ℒ": "\\mathcal{L}",
    "℘": "\\wp",
    "ℬ": "\\mathcal{B}",
    "ℰ": "\\mathcal{E}",
    "ℱ": "\\mathcal{F}",
    "ℋ": "\\mathcal{H}",
    "ℐ": "\\mathcal{I}",
    "ℳ": "\\mathcal{M}",
    "ℛ": "\\mathcal{R}",
    "⟨": "\\langle",
    "⟩": "\\rangle",
    "⟦": "\\llbracket",
    "⟧": "\\rrbracket",
    "⟪": "\\llangle",
    "⟫": "\\rrangle",
    "⟬": "\\lBrace",
    "⟭": "\\rBrace",
    "⟵": "\\longleftarrow",
    "⟶": "\\longrightarrow",
    "⟷": "\\longleftrightarrow",
    "⟸": "\\Longleftarrow",
    "⟹": "\\Longrightarrow",
    "⟺": "\\Longleftrightarrow",
    "⟼": "\\longmapsto",
    "⟿": "\\leadsto",
    "⤂": "\\looparrowleft",
    "⤃": "\\looparrowright",
    "⤄": "\\leftrightharpoons",
    "⤅": "\\rightleftharpoons",
    "⤌": "\\curvearrowleft",
    "⤍": "\\curvearrowright",
    "⤎": "\\circlearrowleft",
    "⤏": "\\circlearrowright",
    "⤑": "\\rightsquigarrow",
    "⤒": "\\upuparrows",
    "⤓": "\\downdownarrows",
    "⤝": "\\leftarrowtail",
    "⤞": "\\rightarrowtail",
    "⥰": "\\downfishtail",
    "⥱": "\\upfishtail",
    "⦙": "\\Vert",
    "⦚": "\\lVert",
    "⦛": "\\rVert",
    "⦜": "\\lgroup",
    "⦝": "\\rgroup",
    "⦵": "\\bigodot",
    "⦶": "\\bigotimes",
    "⦷": "\\bigoplus",
    "⦸": "\\biguplus",
    "⦹": "\\bigsqcup",
    "⧀": "\\trianglelefteq",
    "⧁": "\\trianglerighteq",
    "⧂": "\\ntriangleleft",
    "⧃": "\\ntriangleright",
    "⧄": "\\trianglelefteqslant",
    "⧅": "\\trianglerighteqslant",
    "⧉": "\\square",
    "⧮": "\\downdownarrows",
    "⧯": "\\upuparrows",
    "⨀": "\\bigodot",
    "⨁": "\\bigoplus",
    "⨂": "\\bigotimes",
    "⨃": "\\bigcup",
    "⨄": "\\biguplus",
    "⨅": "\\bigcap",
    "⨆": "\\bigsqcup",
    "⨏": "\\fint",
    "⨑": "\\iint",
    "⨒": "\\iiint",
    "⨓": "\\iiiint",
    "⨔": "\\idotsint",
    "⨕": "\\oiint",
    "⨖": "\\oiiint",
    "⨗": "\\ointctrclockwise",
    "⨘": "\\ointclockwise",
    "⨙": "\\sqint",
    "⨚": "\\intlarhk",
    "⨛": "\\intx",
    "⨜": "\\intcap",
    "⨝": "\\intcup",
    "⨞": "\\upint",
    "⨟": "\\lowint",
    "ℶ": "\\beth",
    "ℷ": "\\gimel",
    "ℸ": "\\daleth",
    "ℼ": "\\varpi",
    "ℽ": "\\digamma",
    "ℾ": "\\Gamma",
    "ℿ": "\\Pi",
    "⅀": "\\Sigma",
    "⅁": "\\Game",
    "⅂": "\\turnediota",
    "⅃": "\\Finv",
    "⅄": "\\Yup",
    "⅋": "\\multimap",
    "ↀ": "\\mho",
    "ↁ": "\\eth",
    "ↂ": "\\diagup",
    "↽": "\\leftharpoondown",
    "↾": "\\upharpoonright",
    "↿": "\\upharpoonleft",
    "⇀": "\\rightharpoonup",
    "⇁": "\\rightharpoondown",
    "⇂": "\\downharpoonright",
    "⇃": "\\downharpoonleft",
    "⇄": "\\rightleftarrows",
    "⇅": "\\updownarrows",
    "⇆": "\\leftrightarrows",
    "⇇": "\\leftleftarrows",
    "⇈": "\\upuparrows",
    "⇉": "\\rightrightarrows",
    "⇊": "\\downdownarrows",
    "⇋": "\\leftrightharpoons",
    "⇌": "\\rightleftharpoons",
    "⇍": "\\nLeftarrow",
    "⇎": "\\nRightarrow",
    "⇏": "\\nLeftrightarrow",
    "⇑": "\\Uparrow",
    "⇓": "\\Downarrow",
    "⇕": "\\Updownarrow",
    "⇖": "\\nwarrow",
    "⇗": "\\nearrow",
    "⇘": "\\searrow",
    "⇙": "\\swarrow",
    "⇚": "\\Lleftarrow",
    "⇛": "\\Rrightarrow",
    "⇝": "\\rightsquigarrow",
    "⇞": "\\upuparrows",
    "⇟": "\\downdownarrows",
    "⇠": "\\leftarrowtail",
    "⇡": "\\uparrowtail",
    "⇢": "\\rightarrowtail",
    "⇣": "\\downarrowtail",
    "⇤": "\\mapsfrom",
    "⇥": "\\mapsto",
    "⇵": "\\updownarrowbar",
    "⇶": "\\hookuparrow",
    "⇷": "\\hookdownarrow",
    "⇸": "\\looparrowleft",
    "⇹": "\\looparrowright",
    "⇺": "\\leftrightsquigarrow",
    "⇻": "\\nleftarrow",
    "⇼": "\\nrightarrow",
    "⇽": "\\leftharpoonup",
    "⇾": "\\rightharpoonup",
    "⇿": "\\leftrightharpoons",
    "∁": "\\complement",
    "∆": "\\triangle",
    "∊": "\\in",
    "∌": "\\notni",
    "∍": "\\ni",
    "∔": "\\dotplus",
    "∕": "\\slash",
    "∜": "\\sqrt[4]",
    "∟": "\\angle",
    "∡": "\\measuredangle",
    "∢": "\\sphericalangle",
    "∣": "\\mid",
    "∤": "\\nmid",
    "∥": "\\parallel",
    "∦": "\\nparallel",
    "∯": "\\oiint",
    "∰": "\\oiiint",
    "∱": "\\intclockwise",
    "∲": "\\varointclockwise",
    "∳": "\\ointctrclockwise",
    "∶": ":",
    "∷": "::",
    "∸": "\\dotminus",
    "∹": "\\excess",
    "∺": "\\geomequiv",
    "∻": "\\homothetic",
    "∽": "\\backsim",
    "∾": "\\lazysinv",
    "∿": "\\sinewave",
    "≀": "\\wr",
    "≁": "\\nsim",
    "≂": "\\eqsim",
    "≄": "\\nsimeq",
    "≆": "\\simneqq",
    "≇": "\\ncong",
    "≉": "\\napprox",
    "≋": "\\approxident",
    "≌": "\\backcong",
    "≍": "\\asymp",
    "≎": "\\Bumpeq",
    "≏": "\\bumpeq",
    "≐": "\\doteq",
    "≑": "\\Doteq",
    "≒": "\\fallingdotseq",
    "≓": "\\risingdotseq",
    "≔": ":=",
    "≕": "=:",
    "≖": "\\eqcirc",
    "≗": "\\circeq",
    "≙": "\\corresponds",
    "≚": "\\triangleq",
    "≛": "\\triangleq",
    "≜": "\\def",
    "≝": "\\stackrel{\\mathrm{def}}{=}",
    "≞": "\\questeq",
    "≟": "\\eqsim",
    "≢": "\\nequiv",
    "≣": "\\Equiv",
    "≦": "\\leqq",
    "≧": "\\geqq",
    "≨": "\\lneqq",
    "≩": "\\gneqq",
    "≬": "\\between",
    "≭": "\\nasymp",
    "≮": "\\nless",
    "≯": "\\ngtr",
    "≰": "\\nleq",
    "≱": "\\ngeq",
    "≲": "\\lesssim",
    "≳": "\\gtrsim",
    "≴": "\\nlesssim",
    "≵": "\\ngtrsim",
    "≶": "\\lessgtr",
    "≷": "\\gtrless",
    "≸": "\\notlessgreater",
    "≹": "\\notgreaterless",
    "≺": "\\prec",
    "≻": "\\succ",
    "≼": "\\preceq",
    "≽": "\\succeq",
    "≾": "\\preccurlyeq",
    "≿": "\\succcurlyeq",
    "⊀": "\\nprec",
    "⊁": "\\nsucc",
    "⋉": "\\ltimes",
    "⋊": "\\rtimes",
    "⋋": "\\leftthreetimes",
    "⋌": "\\rightthreetimes",
    "⋍": "\\backsimeq",
    "⋎": "\\curlyvee",
    "⋏": "\\curlywedge",
    "⋐": "\\Subset",
    "⋑": "\\Supset",
    "⋒": "\\Cap",
    "⋓": "\\Cup",
    "⋔": "\\pitchfork",
    "⋕": "\\equalparallel",
    "⋖": "\\lessdot",
    "⋗": "\\gtrdot",
    "⋘": "\\lll",
    "⋙": "\\ggg",
    "⋚": "\\lesseqgtr",
    "⋛": "\\gtreqless",
    "⋜": "\\eqslantless",
    "⋝": "\\eqslantgtr",
    "⋞": "\\curlyeqprec",
    "⋟": "\\curlyeqsucc",
    "⋠": "\\npreccurlyeq",
    "⋡": "\\nsucccurlyeq",
    "⋢": "\\nsqsubseteq",
    "⋣": "\\nsqsupseteq",
    "⋦": "\\lnsim",
    "⋧": "\\gnsim",
    "⋨": "\\precnsim",
    "⋩": "\\succnsim",
    "⋪": "\\ntriangleleft",
    "⋫": "\\ntriangleright",
    "⋬": "\\ntrianglelefteq",
    "⋭": "\\ntrianglerighteq",
    "⋮": "\\vdots",
    "⋯": "\\cdots",
    "⋰": "\\adots",
    "⋱": "\\ddots",
    "⋲": "\\disin",
    "⋳": "\\varisins",
    "⋴": "\\isins",
    "⋵": "\\isindot",
    "⋶": "\\varisinobar",
    "⋷": "\\isinobar",
    "⋸": "\\isinvb",
    "⋹": "\\isinE",
    "⋺": "\\nisd",
    "⋻": "\\varnis",
    "⋼": "\\nis",
    "⋽": "\\varniobar",
    "⋾": "\\niobar",
    "⋿": "\\bagmember",
    "⌀": "\\diameter",
    "⌁": "\\house",
    "⌂": "\\varhouse",
    "⌃": "\\upanglearrow",
    "⌄": "\\downanglearrow",
    "⌅": "\\uparrowbarred",
    "⌆": "\\downarrowbarred",
    "⌇": "\\varmapsfrom",
    "⌌": "\\invneg",
    "⌍": "\\wasylozenge",
    "⌎": "\\ocircle",
    "⌏": "\\oturnedcircle",
    "⌐": "\\neg",
    "⌑": "\\boxquestion",
    "⌒": "\\overset{\\frown}{}",
    "⌓": "\\trianglecdot",
    "⌔": "\\triangledown",
    "⌕": "\\boxadd",
    "⌖": "\\diamondmath",
    "⌗": "\\boxbar",
    "⌘": "\\Command",
    "⌙": "\\triangleminus",
    "⌚": "\\watch",
    "⌛": "\\hourglass",
    "⌜": "\\ulcorner",
    "⌝": "\\urcorner",
    "⌞": "\\llcorner",
    "⌟": "\\lrcorner",
    "⌠": "\\intop",
    "⌡": "\\intbot",
    "⌢": "\\frown",
    "⌣": "\\smile",
    "⌤": "\\varhexagonblack",
    "⌥": "\\Option",
    "⌦": "\\deleq",
    "⌧": "\\squares",
    "⌨": "\\keyboard",
    "⌫": "\\leftdelete",
    "⌬": "\\upslice",
    "⌭": "\\downslice",
    "⌮": "\\logof",
    "⌯": "\\recordright",
    "⌰": "\\APLinput",
    "⌱": "\\APLbox",
    "⌲": "\\APLcomment",
    "⌳": "\\APLupstile",
    "⌴": "\\APLdownstile",
    "⌵": "\\APLinput",
    "⌾": "\\APLcirclestile",
    "⍁": "\\APLdowncaret",
    "⍂": "\\APLupcaret",
    "⍃": "\\APLleftcaret",
    "⍄": "\\APLrightcaret",
    "⍅": "\\APLrightshoe",
    "⍆": "\\APLleftshoe",
    "⍇": "\\APLtilde",
    "⍈": "\\APLhighcircle",
    "⍉": "\\APLlowcircle",
    "⍊": "\\APLrightfloor",
    "⍋": "\\APLupshoe",
    "⍌": "\\APLdownshoe",
    "⍍": "\\APLleftshoe",
    "⍎": "\\APLzilde",
    "⍏": "\\APLsquiggleright",
    "⍐": "\\APLsquiggleleft",
    "⍑": "\\APLboxupcaret",
    "⍒": "\\APLboxdowncaret",
    "⍓": "\\APLupstile",
    "⍔": "\\APLdownstile",
    "⍕": "\\APLboxquestion",
    "⍖": "\\APLboxexclamation",
    "⍗": "\\APLboxbar",
    "⍘": "\\APLrighttack",
    "⍙": "\\APLlefttack",
    "⍚": "\\APLdowntackjot",
    "⍛": "\\APLuptackjot",
    "⍜": "\\APLsquiggledelete",
    "⍝": "\\APLsquiggleselect",
    "⍞": "\\APLquadcolon",
    "⍟": "\\APLstar",
    "⍠": "\\APLdiamond",
    "⍡": "\\APLequal",
    "⍢": "\\APLquad",
    "⍣": "\\APLuparrow",
    "⍤": "\\APLdownarrow",
    "⍥": "\\APLupstile",
    "⍦": "\\APLdownstile",
    "⍧": "\\APLsquare",
    "⍨": "\\APLnotequal",
    "⍩": "\\APLcolon",
    "⍪": "\\APLhook",
    "⍫": "\\APLquadequal",
    "⍬": "\\APLnotless",
    "⍭": "\\APLnotgreater",
    "⍮": "\\APLnotequal",
    "⍯": "\\APLcirclestar",
    "⍰": "\\APLdowncaret",
    "⍱": "\\APLupcaret",
    "⍲": "\\APLleftcaret",
    "⍳": "\\APLrightcaret",
    "⍴": "\\APLleftfloor",
    "⍵": "\\APLrightfloor",
    "⍶": "\\APLleftceil",
    "⍷": "\\APLrightceil",
    "⍸": "\\APLbottomcircle",
    "⍹": "\\APLtopunderscore",
    "⍺": "\\APLrightshoe",
    "⎀": "\\APLcomment",
    "⎁": "\\APLboxcomment",
    "⎂": "\\APLminus",
    "⎃": "\\APLcirc",
    "⎄": "\\APLtilde",
    "⎅": "\\APLdiaeresis",
    "⎆": "\\APLoverbar",
    "⎇": "\\APLzilde",
    "⎈": "\\APLquadcircle",
    "⎉": "\\APLdownstile",
}

UNICODE_TO_LATEX_REG = re.compile("|".join(map(re.escape, UNICODE_TO_LATEX.keys())))


def unicode_to_latex(text: str) -> str:
    # Define a replacement function
    def replace(match: re.Match) -> str:
        return UNICODE_TO_LATEX[match.group(0)]

    # Use re.sub to replace all occurrences

    return UNICODE_TO_LATEX_REG.sub(replace, text)
